package com.dylan.历史.多线程.并发编程的艺术;

import com.dylan.历史.util.SleepUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Dylan on 2018/9/5.
 */
public class 多线程_CyclicBarrier {

    /**
     * 使用CyclicBarrier来实现开始跑步的标识
     */
    public static void main(String[] args) {
        // 跑步者人数
        int num = 9;

        // 开始跑步的标识，每个跑步者都准备好后就可以开始跑步了
        CyclicBarrier begin = new CyclicBarrier(num, () -> System.out.println("开始跑步"));

        // 创建跑道（线程池），每个跑步者一个赛道（线程数与参加赛跑人数相同）
        ExecutorService track = Executors.newFixedThreadPool(num);
        for (int i = 0; i < num; i++) {
            track.execute(new Runner(begin));
        }

        track.shutdown();
    }

    static class Runner implements Runnable {
        private CyclicBarrier begin;

        public Runner(CyclicBarrier begin) {
            this.begin = begin;
        }

        @Override
        public void run() {
            // 模拟跑步者开始跑步前的准备
            SleepUtils.seconds(new Random().nextInt(10));

            try {
                // 标识自己已准备好跑步
                begin.await();
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + " 开始跑步 " + DateFormatUtils.format(new Date(), "mm:ss.SSS"));
        }
    }
}
